﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        private static int proid;
        private const String moduleName = "client_panorama.dll";
        private const int dwEntityList = 0x4D05B34;
        private const int dwGlowObjectManager = 0x5245F50;
        private const int m_iGlowIndex = 0xA40C;
        private const int m_iTeamNum = 0xF4;
        private static int panorama;
        static void Main(string[] args)
        {
            StringBuilder str = new StringBuilder();
            for (int i=0;i<10;i++)
            {
                str.Append(String.Format("{0:X}", new Random().Next()));
            }
            Console.Title = str.ToString();
            panorama = findModule("csgo");
            Console.WriteLine("by 宇宙遨游");
            open();
            String c;
            do
            {
                c = Console.ReadLine();
            } while (c!="exit");
            
        }

       static void open()
        {
            if(panorama <1)
            {
                Console.WriteLine("未检测到游戏,请打开游戏后再开启本程序!");
            }
            while (true)
            {
                int GlowObjectManager = ReadMemoryValue(panorama + dwGlowObjectManager, proid);
                int MyTeamID = 1;
                for (int i = 0; i < 32; i++)
                {
                    int elist = ReadMemoryValue(panorama + dwEntityList + i * 0x10, proid);
                    int teamNum = ReadMemoryValue(elist + m_iTeamNum, proid);
                    int glow = ReadMemoryValue(elist + m_iGlowIndex, proid);
                    if (elist == 0) continue;
                    if (teamNum == 1) continue;
                    WriteMemory<float>(proid, (GlowObjectManager + ((glow * 0x38) + 4)), 1f);
                    WriteMemory<float>(proid, (GlowObjectManager + ((glow * 0x38) + 8)), 0f);
                    WriteMemory<float>(proid, (GlowObjectManager + ((glow * 0x38) + 12)), 0f);
                    WriteMemory<float>(proid, (GlowObjectManager + ((glow * 0x38) + 16)), 1f);
                    WriteMemory<Boolean>(proid, (GlowObjectManager + ((glow * 0x38) + 36)),true);
                }
                Thread.Sleep(5);
            }
           
        }

        #region API

        //从指定内存中读取字节集数据
        [DllImportAttribute("kernel32.dll", EntryPoint = "ReadProcessMemory")]
        public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, int nSize, IntPtr lpNumberOfBytesRead);

        //从指定内存中写入字节集数据
        [DllImportAttribute("kernel32.dll", EntryPoint = "WriteProcessMemory")]
        public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, int nSize, IntPtr lpNumberOfBytesWritten);

        [DllImportAttribute("kernel32.dll", EntryPoint = "WriteProcessMemory")]
        public static extern bool WriteProcessMemoryd(IntPtr hProcess, IntPtr lpBaseAddress, double[] lpBuffer, int nSize, IntPtr lpNumberOfBytesWritten);
        //打开一个已存在的进程对象，并返回进程的句柄
        [DllImportAttribute("kernel32.dll", EntryPoint = "OpenProcess")]
        public static extern IntPtr OpenProcess(int dwDesiredAccess, Boolean bInheritHandle, int dwProcessId);

        //关闭一个内核对象。其中包括文件、文件映射、进程、线程、安全和同步对象等。
        [DllImport("kernel32.dll")]
        private static extern void CloseHandle(IntPtr hObject);

        #endregion

        public static void WriteMemory<T>(int pid,int Adress, object Value)
        {
            try
            {
                byte[] buffer = StructureToByteArray(Value);
                IntPtr hProcess = OpenProcess(2035711, false, pid);
                WriteProcessMemory(hProcess, (IntPtr)Adress, buffer, buffer.Length, IntPtr.Zero);
                CloseHandle(hProcess);
            }
            catch { }
            
        }
        public static byte[] StructureToByteArray(object obj)
        {
            int len = Marshal.SizeOf(obj);

            byte[] arr = new byte[len];

            IntPtr ptr = Marshal.AllocHGlobal(len);

            Marshal.StructureToPtr(obj, ptr, true);
            Marshal.Copy(ptr, arr, 0, len);
            Marshal.FreeHGlobal(ptr);

            return arr;
        }
        public static int ReadMemoryValue(int baseAddress, int pid)
        {
            try
            {
                byte[] buffer = new byte[4];
                //获取缓冲区地址
                IntPtr byteAddress = Marshal.UnsafeAddrOfPinnedArrayElement(buffer, 0);
                //打开一个已存在的进程对象  0x1F0FFF 最高权限
                IntPtr hProcess = OpenProcess(2035711, false, pid);
                //将制定内存中的值读入缓冲区
                ReadProcessMemory(hProcess, (IntPtr)baseAddress, byteAddress, 4, IntPtr.Zero);
                //关闭操作
                CloseHandle(hProcess);
                //从非托管内存中读取一个 32 位带符号整数。
                return Marshal.ReadInt32(byteAddress);
            }
            catch
            {
                return 0;
            }
        }
        public static int findModule(String processName)
        {
            Process[] arrayProcess = Process.GetProcessesByName(processName);
            foreach (Process p in arrayProcess)
            {
                proid = p.Id;
                foreach (ProcessModule pro in p.Modules)
                {
                    if (moduleName.Equals(pro.ModuleName)) {
                        return (int)pro.BaseAddress;
                    };
                }
            }
            return 0;
        }

    }
}
